using System;
using System.ComponentModel.Design;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using System.Text;

namespace AntEater.Integration
{
    /// <summary>
    /// Provides access to common functions for the integration in Visual Studio.
    /// </summary>
    internal static class Utilities
    {
        /// <summary>
        /// Adds the command handler.
        /// </summary>
        /// <param name="provider">The provider.</param>
        /// <param name="invokeHandler">The invoke handler.</param>
        /// <param name="commandId">The command id.</param>
        /// <returns></returns>
        public static OleMenuCommand AddCommand(IServiceProvider provider, EventHandler invokeHandler, int commandId) {
            return Utilities.AddCommand(provider, invokeHandler, null, null, commandId);
        }

        /// <summary>
        /// Adds the command handler.
        /// </summary>
        /// <param name="provider">The provider.</param>
        /// <param name="invokeHandler">The invoke handler.</param>
        /// <param name="queryHandler">The query handler.</param>
        /// <param name="commandId">The command id.</param>
        /// <returns></returns>
        public static OleMenuCommand AddCommand(IServiceProvider provider, EventHandler invokeHandler, EventHandler queryHandler, int commandId) {
            return Utilities.AddCommand(provider, invokeHandler, queryHandler, null, commandId);
        }

        /// <summary>
        /// Adds the command handler.
        /// </summary>
        /// <param name="provider">The provider.</param>
        /// <param name="invokeHandler">The invoke handler.</param>
        /// <param name="queryHandler">The query handler.</param>
        /// <param name="changeHandler">The change handler.</param>
        /// <param name="commandId">The command id.</param>
        /// <returns></returns>
        public static OleMenuCommand AddCommand(IServiceProvider provider, EventHandler invokeHandler, EventHandler queryHandler, EventHandler changeHandler, int commandId) {

            OleMenuCommand command = null;
            OleMenuCommandService menuService = provider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;

            // add menu command to the menu service
            if (menuService != null) {
                CommandID id = Utilities.CreateCommandId(commandId);
                command = new OleMenuCommand(invokeHandler, changeHandler, queryHandler, id);
                menuService.AddCommand(command);
            }

            return command;
        }

        /// <summary>
        /// Creates the command id.
        /// </summary>
        /// <param name="commandId">The command id.</param>
        /// <returns></returns>
        public static CommandID CreateCommandId(int commandId) {
            return new CommandID(Guids.PackageCommandsIdGuid, commandId);
        }

        /// <summary>
        /// Gets the command.
        /// </summary>
        /// <param name="provider">The provider.</param>
        /// <param name="commandId">The command id.</param>
        /// <returns></returns>
        public static OleMenuCommand GetCommand(IServiceProvider provider, int commandId) {

            OleMenuCommand command = null;
            OleMenuCommandService menuService = provider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;

            // find the specified command
            if (menuService != null) {
                CommandID id = Utilities.CreateCommandId(commandId);
                command = (OleMenuCommand)menuService.FindCommand(id);
            }

            return command;
        }

        /// <summary>
        /// Shows the exception.
        /// </summary>
        /// <param name="serviceProvider">The service provider.</param>
        /// <param name="exception">The exception.</param>
        public static void ShowException(IServiceProvider serviceProvider, Exception exception) {
            Utilities.ShowException(serviceProvider, exception, false);
        }

        /// <summary>
        /// Shows the exception.
        /// </summary>
        /// <param name="serviceProvider">The service provider.</param>
        /// <param name="exception">The exception.</param>
        /// <param name="showStackTrace">if set to <c>true</c> [show stack trace].</param>
        public static void ShowException(IServiceProvider serviceProvider, Exception exception, bool showStackTrace) {
            
            StringBuilder message = new StringBuilder(exception.Message);

            if (showStackTrace == true){
                message.AppendLine();
                message.AppendLine("StackTrace:");
                message.AppendLine(exception.StackTrace);
            }

            VsShellUtilities.ShowMessageBox(serviceProvider, message.ToString(), Strings.ApplicationName, OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);

        }
    }
}
